home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.12 Dec 90 / CleanPict Source / ReadPICT.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-29  |  6.9 KB  |  265 lines  |  [TEXT/KAHL]

  1. /*                                            ReadPICT.c                                            */
  2. /*
  3.  * Picture I/O -- more or less from TechNote 154.
  4.  *
  5.  * For some reason, the PICT dimensions do not correctly
  6.  * describe the picture: it loses its 300 dpi resolution
  7.  * when read in. MAGIC scales the PICT by a factor of 4.
  8.  * We should get the "real" scale factor by inserting
  9.  * our function into the StdBits bottleneck.
  10.  */
  11. #include "CleanPICT.h"
  12. #include <SysErr.h>
  13.  
  14. /*
  15.  * See TechNote 27 (original format), and the Essential
  16.  * MacTutor, vol 3, p 417.  (This struct is now unused
  17.  * but, since it typed it in, it might as well stay.)
  18.  */
  19. typedef struct {
  20.     OSType    fType;                    /* 'DRWG' for MacPaint files    */
  21.     short        hdrID;                    /* 'MD' for MacPaint format        */
  22.     short        version;                /* File version                                */
  23.     short        prRec[60];            /* 120 byte print record            */
  24.     Fixed        xOrigin;                /* Drawing origin                            */
  25.     Fixed        yOrigin;                /* Drawing origin                            */
  26.     Fixed        xScale;                    /* Screen resolution                    */
  27.     Fixed        yScale;                    /* Screen resolution                    */        
  28.     short        atrState[31];        /* Drawing attribute state        */
  29.     short        lCnt;                        /* Top-level objects                    */
  30.     short        lTot;                        /* Total number of objects        */
  31.     long        lSiz;                        /* Total size of list                    */
  32.     Fixed        top;                        /* Box enclosing all objects    */
  33.     Fixed        left;
  34.     Fixed        bottom;
  35.     Fixed        right;
  36.     short        filler1[141];        /* 282 bytes unused                        */
  37. } MacDrawHdrRec;
  38.  
  39. static int            PICTfile;    /* The file ioRefNum                    */
  40.  
  41. /*
  42.  * Use this to peek into the bitmap as it is read in.
  43.  * The peeking is done by jumping into the Debugger.
  44.  */
  45. pascal void            myStdBits(
  46.         BitMap *, Rect *, Rect *, int, RgnHandle);
  47. pascal void            read_picture_data(Ptr, int);
  48. pascal void            write_picture_data(Ptr, int);
  49.  
  50. /*
  51.  * read_picture() reads the picture from the PICT file,
  52.  * constructing the window at the proper size.
  53.  */
  54. OSErr
  55. read_picture(window, theFile)
  56. WindowPtr            window;
  57. int                        theFile;
  58. {
  59.         PicHandle                handle;
  60.         QDProcs                    procedures;
  61.         OSErr                        status;
  62.         long                        size;
  63.         long                        place;
  64.         Rect                        box;
  65.         GrafPtr                    oldPort;
  66.         MacDrawHdrRec    header;
  67.         
  68.         PICTfile = theFile;
  69.         handle = (PicHandle) NewHandle(sizeof (Picture));
  70.         if (handle == NIL) {
  71.             DebugStr("\pCan't get memory for picture");
  72.             return (MemError());
  73.         }
  74.         /*
  75.          * Read the MacDraw header record -- that was a
  76.          * good idea, but it didn't work as the headers
  77.          * are garbage.
  78.          */
  79.         if (sizeof header != 512)
  80.             DebugStr("\pMacDrawHdrRec wrong size!");
  81.         read_picture_data((Ptr) &header, sizeof header);
  82.         HLock(handle);
  83.         read_picture_data((Ptr) *handle, sizeof (Picture));
  84.         HUnlock(handle);
  85.         box = (**handle).picFrame;
  86.         DOC.pictSize = box;
  87.         box.right *= MAGIC;
  88.         box.bottom *= MAGIC;
  89.         GetPort(&oldPort);
  90.         DOC.pictPort = CreateOSGrafPort(box);
  91.         if (DOC.pictPort == NIL) {
  92.             DebugStr("\pNo memory for picture");
  93.             SetPort(oldPort);
  94.             return (MemError());
  95.         }
  96.         SetStdProcs(&procedures);
  97.         DOC.pictPort->grafProcs = &procedures;
  98.         procedures.getPicProc = (Ptr) read_picture_data;
  99. /*    procedures.bitsProc = (Ptr) myStdBits;        -- unused    */
  100.         DrawPicture(handle, &box);
  101.         DOC.pictPort->grafProcs = NIL;
  102.         DisposHandle((Handle) handle);
  103.         /*
  104.          * Erase a 1-pixel frame around the picture so
  105.          * the island searcher never has to worry about
  106.          * falling off the end of the universe.
  107.          */
  108.         PenPat(white);
  109.         FrameRect(&DOC.pictSize);
  110.         PenNormal();
  111.         SetPort(oldPort);
  112.         /*
  113.          * Check for errors by getting the file position and
  114.          * checking that it is at the end of file.
  115.          */
  116.         if ((status = GetEOF(PICTfile, &size)) != noErr
  117.          || (status = GetFPos(PICTfile, &place)) != noErr) {
  118.              DebugStr("\pCan't get EOF or file position");
  119.              return (status);
  120.         }
  121.         if (size != place) {
  122.             DebugStr("\pDidn't read entire picture");
  123.             return (dsSysErr);
  124.         }
  125.         /*
  126.          * Ok so far.  Now, change the window size so the
  127.          * picture fills the window -- but keep the proportions
  128.          * as close to the original as possible.
  129.          */
  130.         SetRect(
  131.             &box,
  132.             2,
  133.             GetMBarHeight() * 2,
  134.             width(DOC.pictSize) + 2,
  135.             GetMBarHeight() * 2 + height(DOC.pictSize)
  136.         );
  137.         if (box.bottom > (screenBits.bounds.bottom - 2)) {
  138.             box.bottom = screenBits.bounds.bottom - 2;
  139.             size = height(box);
  140.             box.right = box.left
  141.                 + ((long) width(box) * size) / height(DOC.pictSize);
  142.         }
  143.         if (box.right > (screenBits.bounds.right - 2)) {
  144.             box.right = screenBits.bounds.right - 2;
  145.             size = width(box);
  146.             box.bottom = box.top
  147.                 + ((long) height(box) * size) / width(DOC.pictSize);
  148.         }
  149.         SizeWindow(window, width(box), height(box), TRUE);
  150.         InvalRect(&window->portRect);
  151.         ShowWindow(window);
  152.         return (MemError());
  153. }
  154.  
  155. /*
  156.  * This should implement a "vanilla" StdBits -- for some
  157.  * reason, though, it "bombs" when it runs to completion:
  158.  * perhaps because it's called with a NULL argument at
  159.  * eof.  It was only used to check that the created
  160.  * "MAGIC" bitmap is the same size as the bitmap inside
  161.  * of the PICT -- by running the function under the
  162.  * debugger.
  163.  */
  164. pascal void
  165. myStdBits(srcBits, srcRect, dstRect, mode, maskRgn)
  166. BitMap        *srcBits;
  167. Rect            *srcRect;
  168. Rect            *dstRect;
  169. short            mode;
  170. RgnHandle    maskRgn;
  171. {
  172.         CopyBits(
  173.             srcBits,
  174.             &thePort->portBits, 
  175.             srcRect, dstRect,
  176.             mode,
  177.             maskRgn
  178.         );
  179. }
  180.  
  181. /*
  182.  * Called indirectly to read a chunk of picture data.
  183.  */
  184. pascal void
  185. read_picture_data(data_ptr, byte_count)
  186. Ptr                data_ptr;
  187. int                byte_count;
  188. {
  189.         OSErr                status;
  190.         long                count;
  191.         
  192.         count = byte_count;
  193.         status = FSRead(PICTfile, &count, data_ptr);
  194.         if (status != noErr)
  195.             DebugStr("\pReading picture");
  196. }
  197.  
  198. /*
  199.  * write_picture() writes the current picture to a
  200.  * specified (open) file.  It should be redone to
  201.  * add error handling.
  202.  */
  203. void
  204. write_picture(window, theFile)
  205. WindowPtr            window;
  206. int                        theFile;
  207. {
  208.         PicHandle        picHandle;
  209.         QDProcs            procedures;
  210.         int                    i;
  211.         long                temp;
  212.         Picture            header;
  213.         GrafPtr            tempPort;
  214.         GrafPtr            oldPort;
  215.  
  216.         GetPort(&oldPort);
  217.         PICTfile = theFile;
  218.         /*
  219.          * Write the MacPaint header
  220.          */
  221.         temp = 0L;
  222.         for (i = 0; i < 512; i += sizeof temp)
  223.             write_picture_data((Ptr) &temp, (int) sizeof temp);
  224.         header.picSize = 0;
  225.         header.picFrame = DOC.pictSize;
  226.         write_picture_data((Ptr) &header, (int) sizeof header);
  227.         /*
  228.          * Write the picture by creating a GrafPort with the
  229.          * same dimensions as the original, then drawing the
  230.          * cleaned up picture.
  231.          */
  232.         tempPort = CreateOSGrafPort(DOC.pictSize);
  233.         if (tempPort == NIL) {
  234.             DebugStr("\pNo space for temp port");
  235.             return;
  236.         }
  237.         SetStdProcs(&procedures);
  238.         tempPort->grafProcs = &procedures;
  239.         procedures.putPicProc = (Ptr) write_picture_data;
  240.         picHandle = OpenPicture(&tempPort->portRect);
  241.         CopyOSGrafPort(DOC.pictPort, tempPort, NIL);
  242.         ClosePicture();
  243.         KillPicture(picHandle);
  244.         DeleteOSGrafPort(tempPort);
  245.         DOC.pictPort->grafProcs = NIL;
  246.         SetPort(oldPort);
  247. }
  248.  
  249. /*
  250.  * Called indirectly to write a chunk of picture data.
  251.  */
  252. pascal void
  253. write_picture_data(data_ptr, byte_count)
  254. Ptr                data_ptr;
  255. int                byte_count;
  256. {
  257.         OSErr                status;
  258.         long                count;
  259.         
  260.         count = byte_count;
  261.         status = FSWrite(PICTfile, &count, data_ptr);
  262.         if (status != noErr)
  263.             DebugStr("\pWriting picture");
  264. }
  265.